<?php
define('__PLUGIN_ROOT__', __DIR__);
class GmSSO_Action extends Typecho_Widget implements Widget_Interface_Do
{
    protected $api = "https://account.gmya.net";
    protected $plugin;
    public function __construct()
    {
        $this->plugin = Typecho_Widget::widget('Widget_Options')->plugin('GmSSO');
    }
    public function action(){
        
    }
    
    public function callback(){
        if(empty($this->plugin->client_id) || empty($this->plugin->client_secret)){
            throw new Typecho_Exception(_t('请完成插件配置'));
        }
        if(Typecho_Widget::widget('Widget_User')->hasLogin()) Typecho_Widget::widget('Widget_Options')->response->redirect(Typecho_Common::url('/', Helper::options()->index));
        $request = Typecho_Widget::widget('Widget_Options')->request;
        $code = $request->get("code");
        if($request->get('error') == "cancel") throw new Typecho_Exception(_t('您取消了授权！'));
        if(empty($code)) throw new Typecho_Exception(_t('参数错误！'));
        $curl = curl_init();
        curl_setopt_array($curl, array(
           CURLOPT_URL => "{$this->api}/api/oauth/access_token",
           CURLOPT_RETURNTRANSFER => true,
           CURLOPT_ENCODING => '',
           CURLOPT_MAXREDIRS => 10,
           CURLOPT_TIMEOUT => 5000,
           CURLOPT_FOLLOWLOCATION => true,
           CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
           CURLOPT_CUSTOMREQUEST => 'POST',
           CURLOPT_POSTFIELDS => "client_id={$this->plugin->client_id}&client_secret={$this->plugin->client_secret}&code={$code}",
           CURLOPT_HTTPHEADER => array(
              'User-Agent: GmSSO'
           ),
        ));
        
        $access_token = curl_exec($curl);
        curl_close($curl);
        if(empty($access_token)) throw new Typecho_Exception(_t('账号认证过程中请求认证服务出现异常！'));
        $access_token = json_decode($access_token,true);
        if(empty($access_token)) throw new Typecho_Exception(_t('获取 access_token 出现异常！'));
        if($access_token['code'] != 1) throw new Typecho_Exception(_t($access_token['msg']));
        if(empty($access_token['data']['access_token'])) throw new Typecho_Exception(_t("获取 access_token 错误"));
        
        //获取用户信息
        $curl = curl_init();
        curl_setopt_array($curl, array(
           CURLOPT_URL => "{$this->api}/api/oauth/info",
           CURLOPT_RETURNTRANSFER => true,
           CURLOPT_ENCODING => '',
           CURLOPT_MAXREDIRS => 10,
           CURLOPT_TIMEOUT => 5000,
           CURLOPT_FOLLOWLOCATION => true,
           CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
           CURLOPT_CUSTOMREQUEST => 'POST',
           CURLOPT_POSTFIELDS => "access_token={$access_token['data']['access_token']}",
           CURLOPT_HTTPHEADER => array(
              'User-Agent: GmSSO'
           ),
        ));
        
        $info = curl_exec($curl);
        curl_close($curl);
        if(empty($info)) throw new Typecho_Exception(_t('获取用户信息过程中出现异常！'));
        $info = json_decode($info,true);
        if(empty($info)) throw new Typecho_Exception(_t('获取用户信息出现异常！'));
        if($info['code'] != 1) throw new Typecho_Exception(_t($info['msg']));
        if(empty($info['data']['id'])) throw new Typecho_Exception(_t("获取用户信息错误"));
        $this->check([
            "id" => $info['data']['id'],
            "nickname" => $info['data']['nickname'],
            "email" =>  $info['data']['email'] ? $info['data']['email'] : '',
            "homepage" => $info['data']['homepage'] ? $info['data']['homepage'] : '',
        ]);
    }
    
    //信息处理
    protected function check($data){
        $db = Typecho_Db::get();
        $user = $db->fetchRow($db->select('uid','name')->from('table.users')->where('gm_user_id = ?',$data['id']));
        if($user){
            //存在用户
            $this->login($user['uid']);
        }else{
            //不存在直接注册
            $hasher = new PasswordHash(8, true);
            $insert = array(
                'name' => $this->username(),
                'screenName' => $data['nickname'],
                'mail' => $data['email'],
                'password' => $hasher->HashPassword($this->rands()),
                'url' => $data['homepage'],
                'created' => time(),
                'group' => 'subscriber',
                'gm_user_id' => $data['id']
            );
            $result = Typecho_Widget::widget('Widget_Abstract_Users')->insert($insert);
            if($result){
                $this->login($result);
            }
        }
    }
    
    //设置登录
    protected function login($uid, $expire = 30243600) {
        $db = Typecho_Db::get();
        Typecho_Widget::widget('Widget_User')->simpleLogin($uid);
        $authCode = function_exists('openssl_random_pseudo_bytes') ?
                bin2hex(openssl_random_pseudo_bytes(16)) : sha1(Typecho_Common::randString(20));
        Typecho_Cookie::set('__typecho_uid', $uid, time() + $expire);
        Typecho_Cookie::set('__typecho_authCode', Typecho_Common::hash($authCode), time() + $expire);
        //更新最后登录时间以及验证码
        $db->query($db->update('table.users')->expression('logged', 'activated')->rows(array('authCode' => $authCode))->where('uid = ?', $uid));
        $request = Typecho_Widget::widget('Widget_Options')->request;
        $from = urldecode($request->get("ref"));
        if(!$from){
            $from = Typecho_Common::url('/', Helper::options()->index);
        }
        Typecho_Widget::widget('Widget_Options')->response->redirect($from);
    }
    
    //生成随机字符
    private function rands(){
        $chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        $UserName = "";
        for ( $i = 0; $i < 6; $i++ ){
            $UserName .= @$chars[mt_rand(0, strlen($chars))];
        }
        return strtoupper(base_convert(time() - 1420070400, 10, 36)).$UserName;
    }
    
    //生成用户名
    private function username(){
        $db = Typecho_Db::get();
        $username = $this->rands();
        if($db->fetchAll($db->select('uid')->from('table.users')->where('name = ?', $username)->limit(1))){
            $this->username();
        }
        return $username;
    }
}
